package com.katze.common.socket.server;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.katze.common.CommonUtils;
import com.katze.common.env.AppEnvironment;
import com.katze.common.socket.Writer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.function.Consumer;
import java.util.jar.Attributes;

public class SocketCommandRunnable implements Runnable {
    private static final Logger log = LoggerFactory.getLogger(SocketCommandRunnable.class);
    private final Socket client;
    private final Consumer<Writer> active;

    public SocketCommandRunnable(Socket client, Consumer<Writer> active) {
        this.client = client;
        this.active = active;
    }

    @Override
    public void run() {
        String command = null;
        try (Socket socket = this.client;
             BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
             PrintWriter writer = new PrintWriter(socket.getOutputStream(), true)) {
            command = reader.readLine(); // 获取本次连接任务
            int index = command.indexOf("@");
            Writer item;
            if (index != -1) {
                item = new Writer(command.substring(0, index), command.substring(index + 1));
            } else {
                item = new Writer(command, "");
            }
            switch (item.getOperate()) {
                case "shutdown":
                    try {
                        item.setMessage("应用程序正在关闭...");
                        active.andThen((v) -> writer.write(v.getMessage())).accept(item);
                    } finally {
                        Thread thread = new Thread(() -> {
                            try {
                                Thread.sleep(500L);
                            } catch (InterruptedException ex) {
                                Thread.currentThread().interrupt();
                            }
                            System.exit(0);
                        });
                        thread.setContextClassLoader(getClass().getClassLoader());
                        thread.start();
                    }
                    break;
                case "ping":
                    item.setMessage(String.valueOf(System.currentTimeMillis()));
                    active.andThen((v) -> writer.write(v.getMessage())).accept(item);
                    break;
                case "manifest":
                    File dir = new File(AppEnvironment.APP_HOME.getValue());
                    File[] files = dir.listFiles((file, name) -> name.endsWith(".jar"));
                    if (files != null && files.length > 0) {
                        Attributes attributes = CommonUtils.loadJarManifest(files[0]);
                        item.setMessage(new ObjectMapper().writeValueAsString(attributes));
                    } else {
                        item.setMessage("None");
                    }
                    active.andThen((v) -> writer.write(v.getMessage())).accept(item);
                    break;
                    //服务端才能接受以下指令
                case "online":
                case "offline":
                    item.setMessage(item.getOperate());
                    active.andThen((v) -> writer.write(v.getMessage())).accept(item);
                    break;
            }
        } catch (Exception e) {
            log.error("执行失败,指令:{}", command, e);
        } finally {
            log.debug("执行完毕,指令:{}", command);
        }
    }
}
